package com.ssy.lingxi.marketing.serviceimpl.component.coupon;

import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.common.constant.marketing.BelongTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.marketing.api.model.constant.MkFeignConstants;
import com.ssy.lingxi.marketing.api.model.constant.MkQueueMessageTypeEnum;
import com.ssy.lingxi.marketing.api.model.dto.MarketingQueueDTO;
import com.ssy.lingxi.marketing.entity.coupon.MerchantCouponDetailDO;
import com.ssy.lingxi.marketing.entity.coupon.PlatformCouponDetailDO;
import com.ssy.lingxi.marketing.model.constant.MerchantCouponDetailStatusEnum;
import com.ssy.lingxi.marketing.model.constant.PlatformCouponDetailStatusEnum;
import com.ssy.lingxi.marketing.model.dto.CouponDetailExpireDTO;
import com.ssy.lingxi.marketing.repository.MerchantCouponDetailRepository;
import com.ssy.lingxi.marketing.repository.PlatformCouponDetailRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * 优惠券过期组件
 * @author yzc
 * @version 2.0.0
 * @date 2021/11/25
 */
@Slf4j
@Component
public class CouponDetailExpireComponent {

    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private PlatformCouponDetailRepository platformCouponDetailRepository;
    @Resource
    private MerchantCouponDetailRepository merchantCouponDetailRepository;

    /**
     * 投递优惠券消息到消息队列, 延时处理
     * @param couponDetailExpireDTO 优惠券DTO
     */
    public void sendMqMsgCouponDetailExpire(CouponDetailExpireDTO couponDetailExpireDTO) {
        long currentTimeMillis = System.currentTimeMillis();

        Long validTimeEnd = couponDetailExpireDTO.getValidTimeEnd();
        if (Objects.isNull(validTimeEnd)) {
            log.error("优惠券延时过期消息投递, 过期时间为空, couponDetailId: {}", couponDetailExpireDTO.getCouponDetailId());
            return;
        }

        if (validTimeEnd - currentTimeMillis <= 0) {
            log.error("优惠券延时过期消息投递, 当期时间大于过期时间, couponDetailId: {}, currentTime: {}, validTimeEnd: {}", couponDetailExpireDTO.getCouponDetailId(), currentTimeMillis, validTimeEnd);
            return;
        }

        // 延时投递时间
        long difference = validTimeEnd - currentTimeMillis;
        Integer delayTime;
        if (difference > Integer.MAX_VALUE) {
            delayTime = Integer.MAX_VALUE;
        } else {
            delayTime = (int) difference;
        }

        // 转换为Json字符串，推送至消息队列
        String json = JSONUtil.toJsonStr(couponDetailExpireDTO);

        this.sendMqMsg(json, delayTime,difference);
    }

    private void sendMqMsg(String json, Integer delayTime,Long originDelayTime) {
        try {
            MarketingQueueDTO queueDTO=new MarketingQueueDTO(MkQueueMessageTypeEnum.COUPON_EXPIRE.getCode(), json,originDelayTime);
            // 延迟时间的单位是毫秒
            rabbitTemplate.convertAndSend(MkFeignConstants.MK_DELAY_EXCHANGE, MkFeignConstants.MK_DELAY_ROUTING_KEY, JSONUtil.toJsonStr(queueDTO), message -> {
                message.getMessageProperties().setDelay(delayTime);
                return message;
            });
        } catch (Exception e) {
            log.error("优惠券延时过期推送至消息队列错误，data: " + json + ", error:" + e.getMessage());
        }
    }


    /**
     * 处理优惠券过期消息
     * @param jsonMessage json
     */
    public void handleMqMsgCouponDetailExpire(String jsonMessage) {
        long currentTimeMillis = System.currentTimeMillis();
        CouponDetailExpireDTO couponDetailExpireDTO = JSONUtil.toBean(jsonMessage, CouponDetailExpireDTO.class);
        if (Objects.isNull(couponDetailExpireDTO)) {
            log.error("优惠券延时过期消息处理, couponDetailExpireDTO为空");
        }

        if (BelongTypeEnum.PLATFORM.getCode().equals(couponDetailExpireDTO.getBelongType())) {
            PlatformCouponDetailDO platformCouponDetailDO = platformCouponDetailRepository.findById(couponDetailExpireDTO.getCouponDetailId()).orElse(null);
            if (Objects.isNull(platformCouponDetailDO)) {
                log.error("优惠券延时过期消息处理, 平台优惠券, 未找到领取优惠券couponDetailId: {}", couponDetailExpireDTO.getCouponDetailId());
                return ;
            }

            if (!PlatformCouponDetailStatusEnum.RECEIVE.getCode().equals(platformCouponDetailDO.getStatus())) {
                log.error("优惠券延时过期消息处理, 平台优惠券, 优惠券状态非未使用couponDetailId: {}, CouponDetailStatus: {}", platformCouponDetailDO.getId(), platformCouponDetailDO.getStatus());
                return ;
            }

            if (currentTimeMillis <= platformCouponDetailDO.getValidTimeEnd()) {
                log.error("优惠券延时过期消息处理, 平台优惠券, 优惠券未到过期时间couponDetailId: {}, currentTime: {}, validTimeEnd: {}", platformCouponDetailDO.getId(), currentTimeMillis, platformCouponDetailDO.getValidTimeEnd());
                throw new BusinessException(ResponseCode.MARKETING_SERVICE_ERROR);
            }

            platformCouponDetailDO.setStatus(PlatformCouponDetailStatusEnum.EXPIRE.getCode());
            platformCouponDetailRepository.saveAndFlush(platformCouponDetailDO);

        } else if (BelongTypeEnum.MERCHANT.getCode().equals(couponDetailExpireDTO.getBelongType())) {
            MerchantCouponDetailDO merchantCouponDetailDO = merchantCouponDetailRepository.findById(couponDetailExpireDTO.getCouponDetailId()).orElse(null);
            if (Objects.isNull(merchantCouponDetailDO)) {
                log.error("优惠券延时过期消息处理, 商家优惠券, 未找到领取优惠券couponDetailId: {}", couponDetailExpireDTO.getCouponDetailId());
                return ;
            }

            if (!MerchantCouponDetailStatusEnum.RECEIVE.getCode().equals(merchantCouponDetailDO.getStatus())) {
                log.error("优惠券延时过期消息处理, 平台优惠券, 优惠券状态非未使用couponDetailId: {}, CouponDetailStatus: {}", merchantCouponDetailDO.getId(), merchantCouponDetailDO.getStatus());
                return ;
            }

            if (currentTimeMillis <= merchantCouponDetailDO.getValidTimeEnd()) {
                log.error("优惠券延时过期消息处理, 商家优惠券, 优惠券未到过期时间couponDetailId: {}, currentTime: {}, validTimeEnd: {}", merchantCouponDetailDO.getId(), currentTimeMillis, merchantCouponDetailDO.getValidTimeEnd());
                throw new BusinessException(ResponseCode.MARKETING_SERVICE_ERROR);
            }

            merchantCouponDetailDO.setStatus(MerchantCouponDetailStatusEnum.EXPIRE.getCode());
            merchantCouponDetailRepository.saveAndFlush(merchantCouponDetailDO);
        }
    }

    private Integer processDelayTime(Long currentTimeMillis, Long validTimeEnd) {
        long difference = validTimeEnd - currentTimeMillis;
        Integer delayTime;
        if (difference > Integer.MAX_VALUE) {
            delayTime = Integer.MAX_VALUE;
        } else {
            delayTime = (int) difference;
        }

        return delayTime;
    }
}